/*******************************************************************************
 * FilePath    : /Software/Examples_Ble_MS1642/ble_app_peripheral_uart_led/Src/BSP/PWM.c
 * Version     : 1.0
 * Brief       :
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-03-24 15:42:28
 * LastEditors : AndrewHu
 * LastEditTime: 2023-11-16 18:19:14
 * Description :
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
// #define Test_Printf

#define PWM1_TIM TIM1
#define PWM1_TIM_CH TIM_CHANNEL_2
#define PWM1_TimHandle TimHandle_T1
#define PWM1_TimOcConfig TimOcConfig_T1
#define PWM1_PORT GPIOB
#define PWM1_PIN GPIO_PIN_3
#define PWM1_AFn GPIO_AF1_TIM1 // T1C2

#define PWM2_TIM TIM3
#define PWM2_TIM_CH TIM_CHANNEL_2
#define PWM2_TimHandle TimHandle_T3
#define PWM2_TimOcConfig TimOcConfig_T3
#define PWM2_PORT GPIOB
#define PWM2_PIN GPIO_PIN_5
#define PWM2_AFn GPIO_AF1_TIM3 // T3C2

#define PWM3_TIM TIM1
#define PWM3_TIM_CH TIM_CHANNEL_3
#define PWM3_TimHandle TimHandle_T1
#define PWM3_TimOcConfig TimOcConfig_T1
#define PWM3_PORT GPIOB
#define PWM3_PIN GPIO_PIN_6
#define PWM3_AFn GPIO_AF1_TIM1 // T1C3

#define PWM4_TIM TIM17
#define PWM4_TIM_CH TIM_CHANNEL_1
#define PWM4_TimHandle TimHandle_T17
#define PWM4_TimOcConfig TimOcConfig_T17
#define PWM4_PORT GPIOB
#define PWM4_PIN GPIO_PIN_7
#define PWM4_AFn GPIO_AF2_TIM17 // T17C1N

#define PWM5_TIM TIM14
#define PWM5_TIM_CH TIM_CHANNEL_1
#define PWM5_TimHandle TimHandle_T14
#define PWM5_TimOcConfig TimOcConfig_T14
#define PWM5_PORT GPIOA
#define PWM5_PIN GPIO_PIN_7
#define PWM5_AFn GPIO_AF4_TIM14 // T14C1
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 led_en = 0x00;
u8 pwm_rBuff = 0x00;
u8 pwm_gBuff = 0x00;
u8 pwm_bBuff = 0x00;
u8 pwm_cBuff = 0x00;
u8 pwm_wBuff = 0x00; // 输出

TIM_HandleTypeDef TimHandle_T1;
TIM_OC_InitTypeDef TimOcConfig_T1;

TIM_HandleTypeDef TimHandle_T3;
TIM_OC_InitTypeDef TimOcConfig_T3;

TIM_HandleTypeDef TimHandle_T14;
TIM_OC_InitTypeDef TimOcConfig_T14;

TIM_HandleTypeDef TimHandle_T17;
TIM_OC_InitTypeDef TimOcConfig_T17;
/* Private function ----------------------------------------------------------*/
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    : Fun_PWM_Led_set
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : LED亮度设置
 ******************************************************************************/
void Fun_PWM_Led_set(u8 *arry)
{
    pwm_rBuff = arry[0];
    pwm_gBuff = arry[1];
    pwm_bBuff = arry[2];
    pwm_cBuff = arry[3];
    pwm_wBuff = arry[4];
}
/*******************************************************************************
 * Function    : Fun_PWM1_Set
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : PWM输出占空比设置
 ******************************************************************************/
void Fun_PWM1_Set(u8 value)
{
    static u8 pwm1_buff = 0x00;

    if (pwm1_buff == value)
        return;
    // 关闭输出
    if (HAL_TIM_PWM_Stop(&PWM1_TimHandle, PWM1_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }
    HAL_GPIO_WritePin(PWM1_PORT, PWM1_PIN, GPIO_PIN_RESET);

    // 设置占空比
    PWM1_TimOcConfig.Pulse = value; /* 占空比 */
    if (HAL_TIM_PWM_ConfigChannel(&PWM1_TimHandle, &PWM1_TimOcConfig, PWM1_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }

    // 打开输出
    if (HAL_TIM_PWM_Start(&PWM1_TimHandle, PWM1_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }
    pwm1_buff = value;
}
/*******************************************************************************
 * Function    : Fun_PWM2_Set
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : PWM输出占空比设置
 ******************************************************************************/
void Fun_PWM2_Set(u8 value)
{
    static u8 pwm2_buff = 0x00;

    if (pwm2_buff == value)
        return;

    // 关闭输出
    if (HAL_TIM_PWM_Stop(&PWM2_TimHandle, PWM2_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }
    HAL_GPIO_WritePin(PWM2_PORT, PWM2_PIN, GPIO_PIN_RESET);

    // 更新占空比
    PWM2_TimOcConfig.Pulse = value; /* 占空比 */
    if (HAL_TIM_PWM_ConfigChannel(&PWM2_TimHandle, &PWM2_TimOcConfig, PWM2_TIM_CH) != HAL_OK)
    {
        /* Configuration Error */
        Error_Handler();
    }

    // 打开输出
    if (HAL_TIM_PWM_Start(&PWM2_TimHandle, PWM2_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }

    pwm2_buff = value;
}
/*******************************************************************************
 * Function    : Fun_PWM3_Set
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : PWM输出占空比设置
 ******************************************************************************/
void Fun_PWM3_Set(u8 value)
{
    static u8 pwm3_buff = 0x00;

    if (pwm3_buff == value)
        return;

    // 关闭输出
    if (HAL_TIM_PWM_Stop(&PWM3_TimHandle, PWM3_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }
    HAL_GPIO_WritePin(PWM3_PORT, PWM3_PIN, GPIO_PIN_RESET);

    // 设置占空比
    PWM3_TimOcConfig.Pulse = value; /* 占空比 */
    if (HAL_TIM_PWM_ConfigChannel(&PWM3_TimHandle, &PWM3_TimOcConfig, PWM3_TIM_CH) != HAL_OK)
    {
        /* Configuration Error */
        Error_Handler();
    }

    // 打开输出
    if (HAL_TIM_PWM_Start(&PWM3_TimHandle, PWM3_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }

    pwm3_buff = value;
}
/*******************************************************************************
 * Function    : Fun_PWM4_Set
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : PWM输出占空比设置
 ******************************************************************************/
void Fun_PWM4_Set(u8 value)
{
    static u8 pwm4_buff = 0x00;

    if (pwm4_buff == value)
        return;

    // 关闭输出
    if (HAL_TIMEx_PWMN_Stop(&PWM4_TimHandle, PWM4_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }
    HAL_GPIO_WritePin(PWM4_PORT, PWM4_PIN, GPIO_PIN_RESET);

    // 设置输出占空比
    PWM4_TimOcConfig.Pulse = value; /* 占空比 */
    if (HAL_TIM_PWM_ConfigChannel(&PWM4_TimHandle, &PWM4_TimOcConfig, PWM4_TIM_CH) != HAL_OK)
    {
        /* Configuration Error */
        Error_Handler();
    }

    // 打开输出
    if (HAL_TIMEx_PWMN_Start(&PWM4_TimHandle, PWM4_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }

    pwm4_buff = value;
}
/*******************************************************************************
 * Function    : Fun_PWM5_Set
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : PWM输出占空比设置
 ******************************************************************************/
void Fun_PWM5_Set(u8 value)
{
    static u8 pwm5_buff = 0x00;

    if (pwm5_buff == value)
        return;

    // 关闭输出
    if (HAL_TIM_PWM_Stop(&PWM5_TimHandle, PWM5_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }
    HAL_GPIO_WritePin(PWM5_PORT, PWM5_PIN, GPIO_PIN_RESET);

    // 设置输出占空比
    PWM5_TimOcConfig.Pulse = value; /* 占空比 */
    if (HAL_TIM_PWM_ConfigChannel(&PWM5_TimHandle, &PWM5_TimOcConfig, PWM5_TIM_CH) != HAL_OK)
    {
        /* Configuration Error */
        Error_Handler();
    }

    // 打开输出
    if (HAL_TIM_PWM_Start(&PWM5_TimHandle, PWM5_TIM_CH) != HAL_OK)
    {
        Error_Handler();
    }

    pwm5_buff = value;
}
/*******************************************************************************
 * Function    : Fun_TIM_Init
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : PWM时钟初始化
 ******************************************************************************/
void Fun_TIM_Init(TIM_TypeDef *Tim, TIM_HandleTypeDef *TimHandle, TIM_OC_InitTypeDef *TimOcConfig)
{
    TimHandle->Instance = Tim;                                          /* 选择TIM1 */
    TimHandle->Init.Period = 0xff;                                      /* 自动重装载值 */
    TimHandle->Init.Prescaler = 2 - 1;                                  /* 预分频为2-1 */
    TimHandle->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;             /* 时钟不分频 */
    TimHandle->Init.CounterMode = TIM_COUNTERMODE_UP;                   /* 向上计数 */
    TimHandle->Init.RepetitionCounter = 1 - 1;                          /* 不重复计数 */
    TimHandle->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; /* 自动重装载寄存器没有缓冲 */
    /* 基础时钟初始化 */
    if (HAL_TIM_PWM_Init(TimHandle) != HAL_OK)
    {
        Error_Handler();
    }

    TimOcConfig->OCMode = TIM_OCMODE_PWM1;              /* 输出配置为PWM1 */
    TimOcConfig->OCFastMode = TIM_OCFAST_DISABLE;       /* 输出快速使能关闭 */
    TimOcConfig->OCPolarity = TIM_OCPOLARITY_HIGH;      /* OC通道输出高电平有效 */
    TimOcConfig->OCIdleState = TIM_OCIDLESTATE_RESET;   /* 空闲状态OC1输出低电平 */
    TimOcConfig->OCNPolarity = TIM_OCNPOLARITY_HIGH;    /* OCN通道输出高电平有效 */
    TimOcConfig->OCNIdleState = TIM_OCNIDLESTATE_RESET; /* 空闲状态OC1N输出低电平 */
}
/*******************************************************************************
 * Function    : Fun_PWM_Init
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : PWM初始化
 ******************************************************************************/
void Fun_PWM_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    __HAL_RCC_TIM1_CLK_ENABLE();
    __HAL_RCC_TIM3_CLK_ENABLE();
    __HAL_RCC_TIM14_CLK_ENABLE();
    __HAL_RCC_TIM17_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE(); /* GPIOA时钟使能 */
    __HAL_RCC_GPIOB_CLK_ENABLE(); /* GPIOB时钟使能 */

    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    // PWM1
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pin = PWM1_PIN;
    // GPIO_InitStruct.Alternate = PWM1_AFn;
    HAL_GPIO_Init(PWM1_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(PWM1_PORT, PWM1_PIN, GPIO_PIN_RESET);
    Fun_TIM_Init(PWM1_TIM, &PWM1_TimHandle, &PWM1_TimOcConfig); // PWM初始化
    Fun_PWM1_Set(0x00);
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Alternate = PWM1_AFn;
    HAL_GPIO_Init(PWM1_PORT, &GPIO_InitStruct);

    // PWM2
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pin = PWM2_PIN;
    // GPIO_InitStruct.Alternate = PWM2_AFn;
    HAL_GPIO_Init(PWM2_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(PWM2_PORT, PWM2_PIN, GPIO_PIN_RESET);
    Fun_TIM_Init(PWM2_TIM, &PWM2_TimHandle, &PWM2_TimOcConfig); // PWM初始化
    Fun_PWM2_Set(0x00);
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Alternate = PWM2_AFn;
    HAL_GPIO_Init(PWM2_PORT, &GPIO_InitStruct);

    // PWM3
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pin = PWM3_PIN;
    // GPIO_InitStruct.Alternate = PWM3_AFn;
    HAL_GPIO_Init(PWM3_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(PWM3_PORT, PWM3_PIN, GPIO_PIN_RESET);
    Fun_TIM_Init(PWM3_TIM, &PWM3_TimHandle, &PWM3_TimOcConfig); // PWM初始化
    Fun_PWM3_Set(0x00);
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Alternate = PWM3_AFn;
    HAL_GPIO_Init(PWM3_PORT, &GPIO_InitStruct);

    // PWM4
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pin = PWM4_PIN;
    // GPIO_InitStruct.Alternate = PWM4_AFn;
    HAL_GPIO_Init(PWM4_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(PWM4_PORT, PWM4_PIN, GPIO_PIN_RESET);
    Fun_TIM_Init(PWM4_TIM, &PWM4_TimHandle, &PWM4_TimOcConfig); // PWM初始化
    Fun_PWM4_Set(0x00);
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Alternate = PWM4_AFn;
    HAL_GPIO_Init(PWM4_PORT, &GPIO_InitStruct);

    // PWM5
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pin = PWM5_PIN;
    // GPIO_InitStruct.Alternate = PWM5_AFn;
    HAL_GPIO_Init(PWM5_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(PWM5_PORT, PWM5_PIN, GPIO_PIN_RESET);
    Fun_TIM_Init(PWM5_TIM, &PWM5_TimHandle, &PWM5_TimOcConfig); // PWM初始化
    Fun_PWM5_Set(0x00);
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Alternate = PWM5_AFn;
    HAL_GPIO_Init(PWM5_PORT, &GPIO_InitStruct);
}
/*******************************************************************************
 * Function    : Fun_Pwm_Run
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 18:10:54
 * Description :
 ******************************************************************************/
void Fun_Pwm_Run(void)
{
#ifdef Test_Printf
    static u8 i = 0;

    i++;
    if (i < 5)
        return;

    i = 0x00;
    // if (pwm_rBuff == 0x00)
    // {
    //     pwm_rBuff = 0x80;
    //     pwm_gBuff = 0x80;
    //     pwm_bBuff = 0x80;
    //     pwm_cBuff = 0x80;
    //     pwm_wBuff = 0x80;
    // }
    // else
    // {
    //     pwm_rBuff = 0x00;
    //     pwm_gBuff = 0x00;
    //     pwm_bBuff = 0x00;
    //     pwm_cBuff = 0x00;
    //     pwm_wBuff = 0x00;
    // }
    if (pwm_rBuff)
    {
        if (pwm_cBuff > 0)
            pwm_cBuff--;
        else
            pwm_rBuff = 0x00;

        pwm_wBuff = pwm_cBuff;
    }
    else
    {
        if (pwm_cBuff < 0xff)
            pwm_cBuff++;
        else
            pwm_rBuff = 0xff;

        pwm_wBuff = pwm_cBuff;
    }
#endif

    Fun_PWM1_Set(pwm_cBuff); // c
    Fun_PWM2_Set(pwm_gBuff); // g
    Fun_PWM3_Set(pwm_wBuff); // w
    Fun_PWM4_Set(pwm_bBuff); // b
    Fun_PWM5_Set(pwm_rBuff); // r
}
